﻿using Angle.Krill.Utils;
using Angle.Krill.WinFile;
using AntdUI;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using System.Windows.Forms;
using WeifenLuo.WinFormsUI.Docking;

namespace Angle.Krill
{
    public partial class Explorer : DummyWindow
    {
        private TreeItem selectItems = null;
        private AntdUI.IContextMenuStripItem[] rightMenuForFolder = null;
        private AntdUI.IContextMenuStripItem[] rightMenuForFile = null;
        public Explorer()
        {
            InitializeComponent();
        }

        private void Explorer_Load(object sender, EventArgs e)
        {
            this.Icon = ImageHelper.ConvertToIcon(ImageHelper.CertificateIcon);

            DriveInfo[] driveInfos = DriveInfo.GetDrives();
            this.SetIgnoreCaseImage();
            this.SetMatchWholeImage();
            this.treeExplorer.PauseLayout = true;
            decimal conversionValue = 1073741824;
            foreach (DriveInfo driveInfo in driveInfos)
            {
                var it = new AntdUI.TreeItem($"{driveInfo.Name}({(driveInfo.TotalFreeSpace / conversionValue).ToString("f2")}/{(driveInfo.TotalSize / conversionValue).ToString("f2")})");
                it.Tag = driveInfo.Name;

                this.treeExplorer.Items.Add(it);
            }
            this.treeExplorer.PauseLayout = false;
            this.InitializeRightMenu();
        }

        private void InitializeRightMenu()
        {
            this.rightMenuForFolder = new AntdUI.IContextMenuStripItem[]
            {
                new AntdUI.ContextMenuStripItem("打开"){
                    Tag="OpenFolder"
                },
                new AntdUI.ContextMenuStripItem("新建"){
                    Tag="New",
                    Sub= new AntdUI.IContextMenuStripItem[]
                    {
                        new AntdUI.ContextMenuStripItem("文件"){
                            Tag="NewFile",
                            Icon = ImageHelper.FileIcon,
                        },
                        new AntdUI.ContextMenuStripItem("文件夹"){
                            Tag="NewFolder",
                            Icon = ImageHelper.FolderIcon,
                        },
                    }
                },
                new AntdUI.ContextMenuStripItem("刷新"){
                    Tag="Refresh"
                },
                new AntdUI.ContextMenuStripItemDivider(),
                new AntdUI.ContextMenuStripItem("在文件资源管理器打开"){
                    Icon = ImageHelper.OpenFolderIcon,
                    Tag="OpenToFileExplorer"
                },
                new AntdUI.ContextMenuStripItemDivider(),
                new AntdUI.ContextMenuStripItem("删除","Del"){
                    Icon = ImageHelper.RemoveIcon,
                    Tag="Del"
                },
            };

            this.rightMenuForFile = new AntdUI.IContextMenuStripItem[]
            {
                new AntdUI.ContextMenuStripItem("打开"){
                    Tag="OpenFile"
                },
                new AntdUI.ContextMenuStripItemDivider(),
                new AntdUI.ContextMenuStripItem("在文件资源管理器打开"){
                    Icon = ImageHelper.OpenFolderIcon,
                    Tag="OpenToFileExplorer"
                },
            };
        }

        private void treeExplorer_NodeMouseDoubleClick(object sender, MouseEventArgs args, TreeItem item, Rectangle rect)
        {
            string dirName = string.Empty;
            if (item.Tag is FolderInfoExt folderInfo)
            {
                dirName = folderInfo.FolderPath;
            }
            else if (item.Tag is String s)
            {
                dirName = s;
            }
            else if (item.Tag is FileInfoExt fileInfo)
            {
                FileHelper.ProcessStart(fileInfo.PhysicalPath, fileLockCallback);

                return;
            }

            this.BindData(item);
        }

        private void treeExplorer_NodeMouseClick(object sender, MouseEventArgs args, TreeItem item, Rectangle rect)
        {
            selectItems = item;

            if (item.Sub.Count <= 0)
            {
                return;
            }

            this.SwitchIcon(item, !item.Expand);
        }
        /// <summary>
        /// 切换展开收起图标
        /// </summary>
        /// <param name="item"></param>
        private void SwitchIcon(TreeItem item, bool isExpand)
        {
            if (isExpand)
            {
                item.Icon = ImageHelper.OpenFolderIcon;
            }
            else
            {
                item.Icon = ImageHelper.FolderIcon;
            }
        }

        private void treeExplorer_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Right)
            {
                this.HookRightMenu();
            }
        }

        private void HookRightMenu()
        {
            AntdUI.IContextMenuStripItem[] bindRightMenu = null;
            if (this.selectItems == null)
            {
                this.ParentForm.Info("选择节点");

                return;
            }

            TreeItem treeItem = this.selectItems;
            if (treeItem?.Tag is FileInfoExt)
            {
                bindRightMenu = this.rightMenuForFile;
            }
            else if (treeItem?.Tag is FolderInfoExt)
            {
                bindRightMenu = this.rightMenuForFolder;
            }
            else
            {
                return;
            }

            AntdUI.ContextMenuStrip.open(this.treeExplorer, it =>
            {
                string path = string.Empty;
                if (treeItem?.Tag is FileInfoExt fileInfoExt)
                {
                    path = fileInfoExt.PhysicalPath;
                }
                else if (treeItem?.Tag is FolderInfoExt folderInfoExt)
                {
                    path = folderInfoExt.FolderPath;
                }
                if (it.Tag?.ToString() == "OpenToFileExplorer")
                {
                    this.OpenToFileExplorer(path);
                }
                else if (it.Tag?.ToString() == "NewFile")
                {
                    OperateFileHelper.Instance.NewFile(path, (f) =>
                    {
                        f.FormClosed += New_FormClosed;
                    });
                }
                else if (it.Tag?.ToString() == "NewFolder")
                {
                    OperateFileHelper.Instance.NewFolder(path, (f) =>
                    {
                        f.FormClosed += New_FormClosed;
                    });
                }
                else if (it.Tag?.ToString() == "Refresh")
                {
                    this.BindData(this.selectItems);
                }
                else if (it.Tag?.ToString() == "OpenFile")
                {
                    this.OpenFile(treeItem?.Tag as FileInfoExt);
                }
                else if (it.Tag?.ToString() == "OpenFolder")
                {
                    this.OpenFolder(treeItem?.Tag as FolderInfoExt);
                }
                else if (it.Tag?.ToString() == "Del")
                {
                    this.DelFile(treeItem?.Tag);
                }
            }, bindRightMenu);
        }

        private void DelFile(object tag)
        {
            string path = string.Empty;
            if (tag is FileInfoExt fileInfoExt)
            {
                FileList fileList = AutoMapperHelper.AutoMapperTo<FileInfoExt, FileList>(fileInfoExt);
                OperateFileHelper.Instance.DelFile(new List<FileList> { fileList }, this.ParentForm, () =>
                {
                    this.BindData(this.selectItems);
                }, fileLockCallback);
            }
            else if (tag is FolderInfoExt folderInfoExt)
            {
                path = folderInfoExt.FolderPath;

                OperateFileHelper.Instance.DelFolderFile(path, this.ParentForm, () =>
                {
                    //folderInfoExt.FolderPath = folderInfoExt.FolderPath.Substring(0, folderInfoExt.FolderPath.LastIndexOf("\\"));

                    this.BindData(this.selectItems.PARENTITEM);
                });
            }
        }

        private void New_FormClosed(object sender, FormClosedEventArgs e)
        {
            this.BindData(this.selectItems);
        }

        private void OpenFolder(FolderInfoExt folderInfoExt)
        {
            string selectFolderPath = folderInfoExt.FolderPath;
            DockPanel dockPanel = (this.ParentForm as Main).DockPanel;
            dockPanel.ShowFilesForm(selectFolderPath);
        }

        /// <summary>
        /// 打开文件
        /// </summary>
        /// <param name="fileInfoExt"></param>
        private void OpenFile(FileInfoExt fileInfoExt)
        {
            FileHelper.ProcessStart(fileInfoExt.PhysicalPath, fileLockCallback);
        }

        private void OpenToFileExplorer(string path)
        {
            FileHelper.ProcessStart(new ProcessStartInfo
            {
                Arguments = Path.GetDirectoryName(path),
                FileName = "explorer.exe"
            });
        }

        private void fileLockCallback()
        {
            this.ParentForm.Info("文件已被占用!");
        }

        private void BindData(TreeItem item)
        {
            string dirName = string.Empty;
            if (item.Tag is FolderInfoExt folderInfo)
            {
                dirName = folderInfo.FolderPath;
            }
            else if (item.Tag is String s)
            {
                dirName = s;
            }
            else
            {
                return;
            }
            var lst = FileHelper.GetFolderAndFiles(dirName);

            this.treeExplorer.PauseLayout = true;
            List<TreeItem> treeItems = new List<TreeItem>();
            foreach (var folder in lst.FolderCollection)
            {
                var it = new AntdUI.TreeItem($"{folder.FolderName}");
                it.Tag = folder;
                it.Icon = ImageHelper.FolderIcon;

                treeItems.Add(it);
            }
            foreach (var file in lst.FileCollection)
            {
                var it = new AntdUI.TreeItem($"{file.Name}");
                it.Tag = file;
                it.Icon = ImageHelper.FileIcon;

                treeItems.Add(it);
            }

            item.Sub.Clear();
            item.Sub.AddRange(treeItems);

            item.Expand = true;

            this.SwitchIcon(item, item.Expand);

            this.treeExplorer.PauseLayout = false;
        }

        private void txtSearchFileName_KeyDown(object sender, KeyEventArgs e)
        {
            string searchText = this.txtSearchFileName.Text.Trim();
            if (e.KeyCode == Keys.Enter)
            {
                var sw = Stopwatch.StartNew();
                var rootNode = this.GetRootNode(this.selectItems);
                if (null == rootNode)
                {
                    MessageHelper.Info(this, "选择需要查询的盘符");
                    return;
                }
                if (string.IsNullOrEmpty(rootNode.Tag?.ToString()))
                {
                    MessageHelper.Info(this, "无效查询节点");
                    return;
                }
                string vName = rootNode.Tag?.ToString();

                bool ignoreCase = Boolean.Parse(this.btnIgnoreCase.Tag?.ToString());
                bool matchWhole = Boolean.Parse(this.btnMatchWhole.Tag?.ToString());

                Main fMain = this.ParentForm as Main;
                string title = $"搜索结果：{searchText}";
                var dockContent = DockHelper.FindDocument(fMain.DockPanel, (f) =>
                {
                    return f.Text == title;
                });
                if (null == dockContent)
                {
                    SearchFiles sf = new SearchFiles(vName, searchText, ignoreCase, matchWhole);
                    sf.Text = title;
                    DockHelper.Show(fMain.DockPanel, sf, DockState.Document);
                }
                else
                {
                    if (dockContent is SearchFiles sf)
                    {
                        sf.BindData(vName, searchText, ignoreCase, matchWhole);
                    }
                }

                MessageHelper.Info(this, searchText);
            }
        }

        private TreeItem GetRootNode(TreeItem selectItems)
        {
            var nodeItem = selectItems;
            while (nodeItem?.PARENTITEM != null)
            {
                nodeItem = nodeItem.PARENTITEM;
            }

            return nodeItem;
        }

        private void btnIgnoreCase_Click(object sender, EventArgs e)
        {
            this.SetIgnoreCaseImage();
        }

        private void SetIgnoreCaseImage()
        {
            bool ignoreCase = !Boolean.Parse(this.btnIgnoreCase.Tag?.ToString());
            this.btnIgnoreCase.Tag = ignoreCase;
            if (ignoreCase)
            {
                this.btnIgnoreCase.Image = ImageHelper.GetBitmap("fa-font");
            }
            else
            {
                this.btnIgnoreCase.Image = ImageHelper.GetBitmap("fa-font", Color.FromArgb(0, 122, 204));
            }
        }

        private void btnMatchWhole_Click(object sender, EventArgs e)
        {
            this.SetMatchWholeImage();
        }

        private void SetMatchWholeImage()
        {
            bool matchWhole = !Boolean.Parse(this.btnMatchWhole.Tag?.ToString());
            this.btnMatchWhole.Tag = matchWhole;
            if (matchWhole)
            {
                this.btnMatchWhole.Image = ImageHelper.GetBitmap("fa-align-justify", Color.FromArgb(0, 122, 204));
            }
            else
            {
                this.btnMatchWhole.Image = ImageHelper.GetBitmap("fa-align-justify");
            }
        }
    }
}
